package org.jadelyre.core.task;


import org.jadelyre.core.exception.JadelyreException;
import org.jadelyre.core.worker.Worker;

public abstract class Task<T> implements Runnable {

    //    private ConcurrentLinkedQueue<T> taskQueue = new ConcurrentLinkedQueue<>();
//    protected ThreadPoolExecutor executor;
//    protected TaskQueue<T> taskQueue;
    private Worker<T> worker;

//    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

//    private volatile boolean executed = false;
//    private volatile boolean terminated = false;

//    /**
//     * 添加任务
//     * @param t
//     * @return boolean
//     */
//    public Task addTask(T t){
//        taskQueue.add(t);
//        return this;
//    }

    public Task(Worker<T> worker) {
        this.worker = worker;
    }

    @Override
    public void run() {
        if (worker.isTerminated() || !isStarted()) {
            return;
        }
        try {
            while (true) {
                T t = worker.getEntryQueue().takeEntry();
                if (null == t) {
                    break;
                }
                work(t);
            }
        } catch (Exception e) {
            throw new JadelyreException(e);
        } finally {
            worker.getTaskCount().getAndDecrement();
//            readWriteLock.writeLock().lock();
//            executed = false;
//            readWriteLock.writeLock().unlock();
//            if (!taskQueue.isEmpty()){
//                execute();
//            }
        }

    }
    //设计目标尽可能减少锁的粒度和复杂度
//    public void execute(){
//        if (executor.isShutdown()){
//            return;
//        }
//        readWriteLock.writeLock().lock();
//        this.executed = true;
//        executor.execute(this);
//        readWriteLock.writeLock().unlock();
//
////        先读锁判断
//        readWriteLock.readLock().lock();
//        if (executed){
//            return;
//        }
//        readWriteLock.readLock().unlock();
////        写锁判断
//        readWriteLock.writeLock().lock();
//        if (executed){
//            return;
//        }
//        executed = true;
//        executor.execute(this);
//        readWriteLock.writeLock().unlock();
//    }

    protected abstract <T> void work(T t) throws Exception;

    protected abstract boolean isStarted();
//    public void setTerminated(boolean terminated) {
//        this.terminated = terminated;
//    }


}
